home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / kms20src.lha / KMSC / parse.c < prev    next >
C/C++ Source or Header  |  1994-10-14  |  42KB  |  1,513 lines

  1. /**********************************
  2.  *              KMS               *
  3.  **********************************
  4.  *  ©1992 by BlackMagic Software  *
  5.  **********************************
  6.  *                                *
  7.  **********************************/
  8.  
  9. #include <KMS/KMS.h>
  10. #include <KMS/KMS_devlib.h>
  11. #include <workbench/workbench.h>
  12. #include <workbench/icon.h>
  13. #include <workbench/startup.h>
  14. #include <clib/icon_protos.h>
  15.  
  16. Prototype BOOL ParseArgs(VOID);
  17. Prototype BOOL ParseToolTypes(struct WBStartup *);
  18. Prototype UBYTE ParsePrint(STRPTR, UWORD);
  19. Prototype UWORD CmdParse(STRPTR, UWORD);
  20. Prototype BOOL CmdInterpreter(VOID);
  21. Prototype BOOL CmdExecute(UWORD);
  22. Prototype UWORD CmdSearch(STRPTR);
  23. Prototype BOOL CmpArg(UBYTE, STRPTR);
  24. Prototype STRPTR MsgStringParse(STRPTR, STRPTR, UWORD);
  25. Prototype STRPTR StdStringParse(STRPTR, STRPTR, UWORD);
  26. Prototype BOOL ParseRange(STRPTR);
  27. Prototype BOOL ChatInterpreter(STRPTR);
  28. Prototype BOOL ChatCmd(STRPTR);
  29.  
  30. /*****************************
  31.  * Externe Globale Variablen *
  32.  *****************************/
  33.  
  34. extern struct KMSBase *KMSBase;
  35. extern struct LocalConfig *KMS_LC;
  36.  
  37. extern BOOL Immediate;
  38. extern BOOL PreLogin;
  39. extern BOOL AutoShutDown;
  40. extern BOOL OwnScreen;
  41. extern TEXT PreUser[];
  42. extern BOOL UsePCFont;
  43.  
  44. extern TEXT PathString[];
  45.  
  46. extern UMSAccount SysUMSAccount, MyUMSAccount;
  47. extern UBYTE ShutDown, Plop;
  48.  
  49. extern BOOL Spying;
  50.  
  51. /*********************
  52.  * Globale Variablen *
  53.  *********************/
  54.  
  55. STRPTR CmdArgV[MAXCMDARGS];
  56. UBYTE CmdArgC;
  57.  
  58. STRPTR PPArg = NULL, PPArg2 = NULL, PPArg3 = NULL, PPArg4 = NULL;
  59.  
  60. /*********************************************
  61.  * Beim Start übergebene Parameter auswerten *
  62.  *********************************************
  63.  * I: ---                                    *
  64.  * O: Fehler: TRUE                           *
  65.  *********************************************/
  66.  
  67. /// "ParseArgs"
  68.  
  69. extern struct RDArgs *ReadArgs(STRPTR, LONG *, struct RDArgs *);
  70. extern VOID FreeArgs(struct RDArgs *);
  71.  
  72. #define TEMPLATE "WINDOW/K,OWNSCREEN/S,REMOTE/S,IMMEDIATE/S,AUTOSHUT/S,USERNAME/K,PASSWORD/K,BPS/K/N,SPYWIN/K,DEVICE/K,UNIT/K/N,PCFONT/S"
  73.  
  74. BOOL ParseArgs(VOID)
  75.    {
  76.    UBYTE n;
  77.    struct UserNode *upoint;
  78.    static struct RDArgs *rargs = NULL;
  79.    ULONG args[12];
  80.  
  81.    for(n = 0; n < 12; n++)
  82.       args[n] = 0;
  83.  
  84.    KMS_LC->Device = DEV_CONSOLE;
  85.    KMS_LC->Session.LineSpeed = 0;
  86.    Immediate = FALSE;
  87.    PreLogin = FALSE;
  88.    AutoShutDown = FALSE;
  89.    OwnScreen = FALSE;
  90.    *PreUser = '\0';
  91.    *KMS_LC->WinDim = '\0';
  92.    *KMS_LC->SpyWin = '\0';
  93.    UsePCFont = FALSE;
  94.    strcpy(KMS_LC->SerDevice, "serial.device");
  95.    KMS_LC->SerUnit = 0;
  96.  
  97.    if (!(rargs=(struct RDArgs *)ReadArgs(TEMPLATE, args, NULL)))
  98.       {
  99.       printf("Bad args.\n");
  100.       return TRUE;
  101.       }
  102.  
  103.    if (args[0]) /* WINDOW/K */
  104.       {
  105.       if (strlen((STRPTR)args[0])+1 <= sizeof(KMS_LC->WinDim))
  106.          strcpy(KMS_LC->WinDim, (STRPTR)args[0]);
  107.       else
  108.          {
  109.          printf("String too long.\n");
  110.          FreeArgs(rargs);
  111.          return TRUE;
  112.          }
  113.       }
  114.    if (args[1]) /* OWNSCREEN/S */
  115.       OwnScreen = TRUE;
  116.    if (args[2]) /* REMOTE/S */
  117.       KMS_LC->Device = DEV_SERIAL;
  118.    if (args[3]) /* IMMEDIATE/S */
  119.       Immediate = TRUE;
  120.    if (args[4]) /* AUTOSHUT/S */
  121.       AutoShutDown = TRUE;
  122.    if (args[5]) /* USERNAME/K */
  123.       {
  124.       if (!(upoint = UserCheck((STRPTR)args[5])))
  125.          {
  126.          printf("User not found.\n");
  127.          FreeArgs(rargs);
  128.          return TRUE;
  129.          }
  130.       else
  131.          {
  132.          strcpy(PreUser, upoint->UserData.Name);
  133.          Immediate = TRUE;
  134.          }
  135.       }
  136.    if (args[6]) /* PASSWORD/K */
  137.       {
  138.       if (*PreUser)
  139.          {
  140.          STRPTR pw = ReadUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, upoint->UserData.RealName,
  141.                                                       UMSTAG_CfgName, "PASSWORD",
  142.                                                       TAG_DONE);
  143.          if (!pw || UMSErrNum(SysUMSAccount))
  144.             {
  145.             printf("Error checking password.\n");
  146.             if (pw)
  147.                FreeUMSConfig(SysUMSAccount, pw);
  148.             FreeArgs(rargs);
  149.             return TRUE;
  150.             }
  151.  
  152.          if (pw)
  153.             FreeUMSConfig(SysUMSAccount, pw);
  154.  
  155.          TEXT varbuff[32] = "";
  156.          GetVar("KMSMB", varbuff, sizeof(varbuff), NULL);
  157.          if (!(MyUMSAccount = UMSRLogin(varbuff, upoint->UserData.RealName, (STRPTR)args[6])))
  158.             {
  159.             printf("Bad password.\n");
  160.             FreeArgs(rargs);
  161.             return TRUE;
  162.             }
  163.          else
  164.             {
  165.             KMS_LC->Session.CurrentUser = upoint;
  166.             strcpy(KMS_LC->Session.Password, (STRPTR)args[6]);
  167.             PreLogin = TRUE;
  168.             }
  169.          }
  170.       else
  171.          {
  172.          printf("No password without username.\n");
  173.          FreeArgs(rargs);
  174.          return TRUE;
  175.          }
  176.       }
  177.  
  178.    if (args[7]) /* BPS/K/N */
  179.       KMS_LC->Session.LineSpeed = *((ULONG *)args[7]);
  180.    
  181.    if (args[8]) /* SPYWIN/K */
  182.       {
  183.       if (strlen((STRPTR)args[8])+1 <= sizeof(KMS_LC->SpyWin))
  184.          strcpy(KMS_LC->SpyWin, (STRPTR)args[8]);
  185.       else
  186.          {
  187.          printf("String too long.\n");
  188.          FreeArgs(rargs);
  189.          return TRUE;
  190.          }
  191.  
  192.       KMS_LC->SpyHandle = Open(KMS_LC->SpyWin, MODE_OLDFILE);
  193.       if (!KMS_LC->SpyHandle)
  194.          {
  195.          printf("Spy window failed to open.\n");
  196.          FreeArgs(rargs);
  197.          return TRUE;
  198.          }
  199.       else
  200.          Spying = TRUE;
  201.       }
  202.    
  203.    if (args[9])
  204.       {
  205.       strncpy(KMS_LC->SerDevice, (STRPTR)args[9], LEN_DOSFILE);
  206.       KMS_LC->SerDevice[LEN_DOSFILE] = '\0';
  207.       }
  208.  
  209.    if (args[10])
  210.       KMS_LC->SerUnit = (UBYTE)*((ULONG *)args[10]);
  211.  
  212.    if (args[11]) /* PCFONT/S */
  213.       UsePCFont = TRUE;
  214.  
  215.    FreeArgs(rargs);
  216.  
  217.    return FALSE;
  218.    }
  219.  
  220. ///
  221.  
  222. /*********************************************
  223.  * Beim WB-Start ToolTypes auswerten         *
  224.  *********************************************
  225.  * I: struct WBStartup *                     *
  226.  * O: Fehler: TRUE                           *
  227.  *********************************************/
  228.  
  229. /// "ParseToolTypes"
  230.  
  231. extern BPTR CurrentDir(BPTR);
  232.  
  233. BOOL ParseToolTypes(struct WBStartup *wbstartup)
  234.    {
  235.    struct DiskObject *dobj = NULL;
  236.    struct Library *icbase = NULL;
  237.    struct WBArg *wbarg = NULL;
  238.    STRPTR *tt, tooltype;
  239.    BPTR olddir = -1;
  240.    struct UserNode *upoint;
  241.    
  242.    KMS_LC->Device = DEV_CONSOLE;
  243.    KMS_LC->Session.LineSpeed = 0;
  244.    Immediate = FALSE;
  245.    PreLogin = FALSE;
  246.    AutoShutDown = FALSE;
  247.    OwnScreen = FALSE;
  248.    *PreUser = '\0';
  249.    *KMS_LC->WinDim = '\0';
  250.    *KMS_LC->SpyWin = '\0';
  251.    strcpy(KMS_LC->SerDevice, "serial.device");
  252.    KMS_LC->SerUnit = 0;
  253.  
  254.    if (!wbstartup)
  255.       return TRUE;
  256.  
  257.    wbarg = wbstartup->sm_ArgList; /* Tool */
  258.    if (wbstartup->sm_NumArgs > 1)
  259.       wbarg++;                    /* First Project */
  260.  
  261.    if (wbarg->wa_Lock && wbarg->wa_Name)
  262.       olddir = CurrentDir(wbarg->wa_Lock);
  263.    else
  264.       return TRUE;
  265.  
  266.    if (icbase = OpenLibrary(ICONNAME, 36))
  267.       dobj = GetDiskObject(wbarg->wa_Name);
  268.  
  269.    if (olddir != -1)
  270.       CurrentDir(olddir);
  271.  
  272.    if (!dobj)
  273.       {
  274.       CloseLibrary(icbase);
  275.  
  276.       return TRUE;
  277.       }
  278.  
  279.    tt = dobj->do_ToolTypes;
  280.  
  281.    if (tooltype = FindToolType(tt, "WINDOW"))
  282.       {
  283.       if (strlen(tooltype)+1 < sizeof(KMS_LC->WinDim))
  284.          strcpy(KMS_LC->WinDim, tooltype);
  285.       else
  286.          {
  287.          FreeDiskObject(dobj);
  288.          CloseLibrary(icbase);
  289.  
  290.          return TRUE;
  291.          }
  292.       }
  293.    else
  294.       strcpy(KMS_LC->WinDim, "CON:0/0//999/KMS Default Window");
  295.  
  296.    if (tooltype = FindToolType(tt, "OWNSCREEN"))
  297.       OwnScreen = TRUE;
  298.  
  299.    if (tooltype = FindToolType(tt, "REMOTE"))
  300.       KMS_LC->Device = DEV_SERIAL;
  301.  
  302.    if (tooltype = FindToolType(tt, "IMMEDIATE"))
  303.       Immediate = TRUE;
  304.  
  305.    if (tooltype = FindToolType(tt, "AUTOSHUT"))
  306.       AutoShutDown = TRUE;
  307.  
  308.    if (tooltype = FindToolType(tt, "USERNAME"))
  309.       {
  310.       if (!(upoint = UserCheck(tooltype)))
  311.          {
  312.          Error("FATAL ERROR: [ParseToolTypes] User not found.");
  313.          FreeDiskObject(dobj);
  314.          CloseLibrary(icbase);
  315.  
  316.          return TRUE;
  317.          }
  318.       else
  319.          {
  320.          strcpy(PreUser, upoint->UserData.Name);
  321.          Immediate = TRUE;
  322.          }
  323.       }
  324.  
  325.    if (tooltype = FindToolType(tt, "PASSWORD"))
  326.       {
  327.       if (*PreUser)
  328.          {
  329.          STRPTR pw = ReadUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, upoint->UserData.RealName,
  330.                                                       UMSTAG_CfgName, "PASSWORD",
  331.                                                       TAG_DONE);
  332.          if (!pw || UMSErrNum(SysUMSAccount))
  333.             {
  334.             Error("FATAL ERROR: [ParseToolTypes] Error reading password.");
  335.  
  336.             if (pw)
  337.                FreeUMSConfig(SysUMSAccount, pw);
  338.  
  339.             FreeDiskObject(dobj);
  340.             CloseLibrary(icbase);
  341.  
  342.             return TRUE;
  343.             }
  344.  
  345.          TEXT varbuff[32] = "";
  346.          GetVar("KMSMB", varbuff, sizeof(varbuff), NULL);
  347.          if (!(MyUMSAccount = UMSRLogin(varbuff, upoint->UserData.RealName, tooltype)))
  348.             {
  349.             Error("FATAL ERROR: [ParseToolTypes] Bad password.");
  350.  
  351.             if (pw)
  352.                FreeUMSConfig(SysUMSAccount, pw);
  353.  
  354.             FreeDiskObject(dobj);
  355.             CloseLibrary(icbase);
  356.  
  357.             return TRUE;
  358.             }
  359.          else
  360.             {
  361.             KMS_LC->Session.CurrentUser = upoint;
  362.             strcpy(KMS_LC->Session.Password, tooltype);
  363.             PreLogin = TRUE;
  364.             if (pw)
  365.                FreeUMSConfig(SysUMSAccount, pw);
  366.             }
  367.          }
  368.       else
  369.          {
  370.          Error("FATAL ERROR: [ParseToolTypes] No password without an username!");
  371.  
  372.          FreeDiskObject(dobj);
  373.          CloseLibrary(icbase);
  374.  
  375.          return TRUE;
  376.          }
  377.       }
  378.  
  379.    if (tooltype = FindToolType(tt, "BPS"))
  380.       KMS_LC->Session.LineSpeed = atol(tooltype);
  381.  
  382.    if (tooltype = FindToolType(tt, "SPYWIN"))
  383.       {
  384.       if (strlen(tooltype)+1 < sizeof(KMS_LC->SpyWin))
  385.          strcpy(KMS_LC->SpyWin, tooltype);
  386.       else
  387.          {
  388.          FreeDiskObject(dobj);
  389.          CloseLibrary(icbase);
  390.  
  391.          return TRUE;
  392.          }
  393.       
  394.       KMS_LC->SpyHandle = Open(KMS_LC->SpyWin, MODE_OLDFILE);
  395.       if (!KMS_LC->SpyHandle)
  396.          {
  397.          Error("FATAL ERROR: [ParseToolTypes] Spy window failed to open.");
  398.  
  399.          FreeDiskObject(dobj);
  400.          CloseLibrary(icbase);
  401.          
  402.          return TRUE;
  403.          }
  404.       else
  405.          Spying = TRUE;
  406.       }
  407.  
  408.    if (tooltype = FindToolType(tt, "DEVICE"))
  409.       {
  410.       if (strlen(tooltype)+1 < sizeof(KMS_LC->SerDevice))
  411.          strcpy(KMS_LC->SerDevice, tooltype);
  412.       else
  413.          {
  414.          FreeDiskObject(dobj);
  415.          CloseLibrary(icbase);
  416.  
  417.          return TRUE;
  418.          }
  419.       }
  420.  
  421.    if (tooltype = FindToolType(tt, "UNIT"))
  422.       KMS_LC->SerUnit = (UBYTE)atoi(tooltype);
  423.  
  424.    FreeDiskObject(dobj);
  425.    CloseLibrary(icbase);
  426.  
  427.    return FALSE;
  428.    }
  429.  
  430. ///
  431.  
  432. /***************************************
  433.  * Text-Interpreter Ausgabe            *
  434.  ***************************************
  435.  * I: Eingabestring, Flags             *
  436.  * O: Break-Code                       *
  437.  ***************************************/
  438.  
  439. /// "ParsePrint"
  440.  
  441. UBYTE ParsePrint(STRPTR input, UWORD flags)
  442.    {
  443.    TEXT output[LEN_PARSEOUT+1];
  444.  
  445.    StdStringParse(input, output, LEN_PARSEOUT);
  446.  
  447.    return Print(output, flags);
  448.    }
  449.  
  450. ///
  451.  
  452. /***************************************
  453.  * Kommando-Parser                     *
  454.  ***************************************
  455.  * I: STRPTR inbuff, UWORD inzeig      *
  456.  * O: Neuer Wert von inzeig:           *
  457.  * O: Position in Kommandozeile        *
  458.  * O: (0: Zeilenende wurde erreicht)   *
  459.  ***************************************/
  460.  
  461. /// "CmdParse"
  462.  
  463. UWORD CmdParse(STRPTR inbuff, UWORD inzeig)
  464.    {
  465.    UWORD anfang = 0;
  466.    TEXT c;
  467.  
  468.    CmdArgC = 0;
  469.  
  470.    if (CmdArgV[0])
  471.       {
  472.       free(CmdArgV[0]);
  473.       CmdArgV[0] = NULL;
  474.       }
  475.  
  476.    while(inbuff[inzeig] == ' ')
  477.       inzeig++;
  478.  
  479.    do
  480.       {
  481.       if (inbuff[inzeig] == '"')
  482.          {
  483.          inzeig++;
  484.          anfang = inzeig;
  485.          while((c = inbuff[inzeig]) != '"' && c != '\0')
  486.             inzeig++;
  487.          }
  488.       else if (inbuff[inzeig] == '\'')
  489.          {
  490.          inzeig++;
  491.          anfang = inzeig;
  492.          while((c = inbuff[inzeig]) != '\'' && c != '\0')
  493.             inzeig++;
  494.          }
  495.       else if (CmdArgC == 0 && inbuff[inzeig] == '@')
  496.          {
  497.          anfang = inzeig;
  498.          inzeig++;
  499.          }
  500.       else
  501.          {
  502.          anfang = inzeig;
  503.          while((c = inbuff[inzeig]) != ' ' && c != ';' && c != '\0')
  504.             inzeig++;
  505.          }
  506.  
  507.       CmdArgV[CmdArgC] = (STRPTR)malloc(inzeig-anfang+1);
  508.       if (!CmdArgV[CmdArgC])
  509.          {
  510.          SystemError("CmdParse", "Out of Memory");
  511.          CmdArgC = 0;
  512.          c = '\0';
  513.          }
  514.       else
  515.          {
  516.          strncpy(CmdArgV[CmdArgC], &inbuff[anfang], inzeig-anfang);
  517.          CmdArgV[CmdArgC][inzeig-anfang] = '\0';
  518.          CmdArgC++;
  519.          if ((CmdArgC < MAXCMDARGS) && CmdArgV[CmdArgC])
  520.             {
  521.             free(CmdArgV[CmdArgC]);
  522.             CmdArgV[CmdArgC] = NULL;
  523.             }
  524.          if (c == '"' || c == '\'')
  525.             inzeig++;
  526.          while((c = inbuff[inzeig]) == ' ')
  527.             inzeig++;
  528.          }
  529.       } while(c != '\0' && c != ';' && CmdArgC < MAXCMDARGS);
  530.  
  531.    if (c != '\0' && c != ';')
  532.       {
  533.       /*
  534.       SysMsg(TOO_MANY_PARAMS);
  535.       */
  536.       while((c = inbuff[inzeig]) != ';' && c != '\0')
  537.          inzeig++;
  538.       }
  539.    else if (c == ';')
  540.       inzeig++;
  541.  
  542.    if (c == '\0')
  543.       inzeig = 0;
  544.  
  545.    return inzeig;
  546.    }
  547.  
  548. ///
  549.  
  550. /***************************************
  551.  * Kommando-Interpreter                *
  552.  ***************************************
  553.  * I: ---                              *
  554.  * O: keepgoing                        *
  555.  ***************************************/
  556.  
  557. /// "CmdInterpreter"
  558.  
  559. BOOL CmdInterpreter(VOID)
  560.    {
  561.    BOOL keepgoing = TRUE;
  562.    UWORD inzeig = 0;
  563.  
  564.    do
  565.       {
  566.       inzeig = CmdParse(KMS_LC->Session.InputBuffer, inzeig);
  567.  
  568.       if (CmdArgC)
  569.          keepgoing = CmdExecute(CmdSearch(CmdArgV[0]));
  570.  
  571.       } while(inzeig && keepgoing);
  572.  
  573.    return keepgoing;
  574.    }
  575.  
  576. ///
  577.  
  578. /***************************************
  579.  * Kommando ausführen                  *
  580.  ***************************************
  581.  * I: Befehlsnummer                    *
  582.  * O: Logout: FALSE, Weiter: TRUE      *
  583.  ***************************************/
  584.  
  585. /// "CmdExecute"
  586.  
  587. BOOL CmdExecute(UWORD cmdnum)
  588.    {
  589.    if (cmdnum)
  590.       {
  591.       struct CommandNode *cpoint = KMSBase->CommandList.mlh_Head;
  592.       
  593.       while(cpoint->Node.mln_Succ && cpoint->ID != cmdnum)
  594.          cpoint = cpoint->Node.mln_Succ;
  595.  
  596.       strcpy(KMS_LC->Session.CurrCmd, cpoint->Name);
  597.       }
  598.  
  599.    switch(cmdnum)
  600.       {
  601.       case 0:
  602.          SysMsg(UNKNOWN_COMMAND);
  603.          break;
  604.       case 1:
  605.          Cmd_BRETT();
  606.          break;
  607.       case 2:
  608.          Cmd_INHALT();
  609.          break;
  610.       case 3:
  611.          Cmd_LESEN();
  612.          break;
  613.       case 4:
  614.          Cmd_SCHREIBEN();
  615.          break;
  616.       case 5:
  617.          Cmd_UMSINFO();
  618.          break;
  619.       case 6:
  620.          Cmd_QMARK();
  621.          break;
  622.       case 7:
  623.          Cmd_HILFE();
  624.          break;
  625.       case 8:
  626.          Cmd_PDIR();
  627.          break;
  628.       case 9:
  629.          Cmd_HISTORY();
  630.          break;
  631.       case 10:
  632.          Cmd_UMSDIR();
  633.          break;
  634.       case 11:
  635.          Cmd_AEDIT();
  636.          break;
  637.       case 12:
  638.          Cmd_UMSEXPIRE();
  639.          break;
  640.       case 13:
  641.          Cmd_PEDIT();
  642.          break;
  643.       case 14:
  644.          Cmd_PDELETE();
  645.          break;
  646.       case 15:
  647.          Cmd_DELETE();
  648.          break;
  649.       case 16:
  650.          Cmd_BITED();
  651.          break;
  652.       case 17:
  653.          Cmd_ANTWORT();
  654.          break;
  655.       case 18:
  656.          Cmd_USERPREFS();
  657.          break;
  658.       case 19:
  659.          Cmd_DELPROT();
  660.          break;
  661.       case 20:
  662.          Cmd_SELECT();
  663.          break;
  664.       case 21:
  665.          Cmd_HIDE();
  666.          break;
  667.       case 22:
  668.          Cmd_ECHO();
  669.          break;
  670.       case 23:
  671.          Cmd_LABERFILTER();
  672.          break;
  673.       case 24:
  674.          Cmd_VORMERKER();
  675.          break;
  676.       case 25:
  677.          Cmd_SCHREIBMODUS();
  678.          break;
  679.       case 26:
  680.          Cmd_UEDIT();
  681.          break;
  682.       case 27:
  683.          Cmd_UDIR();
  684.          break;
  685.       case 28:
  686.          Cmd_SIGEDIT();
  687.          break;
  688.       case 29:
  689.          SysMsg(USER_LEAVING);
  690.          Plop = PLOP_LOGOUT;
  691.          return FALSE;
  692.          break;
  693.       case 30:
  694.          Cmd_SHUTDOWN();
  695.          break;
  696.       case 31:
  697.          Cmd_INFO();
  698.          break;
  699.       case 32:
  700.          Cmd_ALIAS();
  701.          break;
  702.       case 33:
  703.          Cmd_CHAT();
  704.          break;
  705.       case 34:
  706.          Cmd_TEMPPREFS();
  707.          break;
  708.       case 35:
  709.          Cmd_LOG();
  710.          break;
  711.       case 36:
  712.          Cmd_UPLOAD();
  713.          break;
  714.       case 37:
  715.          Cmd_DOWNLOAD();
  716.          break;
  717.       case 38:
  718.          Cmd_ACLEDIT();
  719.          break;
  720.       case 39:
  721.          Cmd_SYSMSG();
  722.          break;
  723.       case 40:
  724.          Cmd_PORTLIST();
  725.          break;
  726.       case 41:
  727.          Cmd_REREAD();
  728.          break;
  729.       case 42:
  730.          Cmd_EXEC();
  731.          break;
  732.       case 43:
  733.          Cmd_PAUSE();
  734.          break;
  735.       case 44:
  736.          Cmd_PASSWORD();
  737.          break;
  738.       case 45:
  739.          Cmd_PUPLOAD();
  740.          break;
  741.       case 46:
  742.          Cmd_PDOWNLOAD();
  743.          break;
  744.       case 999:
  745.          Cmd_KMSBATCH();
  746.          break;
  747.       default: /* Kommando als ARexx-Skript realisiert? */
  748.          Cmd_KMSREXX(cmdnum);
  749.          break;
  750.       }
  751.  
  752.    return TRUE;
  753.    }
  754.  
  755. ///
  756.  
  757. /***************************************
  758.  * Kommando in Liste suchen            *
  759.  ***************************************
  760.  * I: Befehlswort                      *
  761.  * O: Befehls-ID                       *
  762.  ***************************************/
  763.  
  764. /// "CmdSearch"
  765.  
  766. UWORD CmdSearch(STRPTR cmd)
  767.    {
  768.    struct CommandNode *cpoint;
  769.    UWORD result = 0, minlen, pos = 0;
  770.    TEXT command[LEN_COMMAND+1];
  771.  
  772.    if (!cmd || !*cmd)
  773.       return 0;
  774.  
  775.    if (!strcmp(cmd, "@"))
  776.       return 999;
  777.  
  778.    cpoint = KMSBase->CommandList.mlh_Head;
  779.  
  780.    /* Gegebenes Kommando in Großbuchstaben wandeln */
  781.  
  782.    Upper(cmd);
  783.  
  784.    /* Jetzt suchen */
  785.  
  786.    while(cpoint->Node.mln_Succ && !result)
  787.       {
  788.       pos = 0;
  789.       minlen = 0;
  790.  
  791.       while(cpoint->Name[pos] && ((cpoint->Name[pos] >= 'A' && cpoint->Name[pos] <= 'Z') || strchr("ÖÄÜ", cpoint->Name[pos])))
  792.          {
  793.          minlen++;
  794.          pos++;
  795.          }
  796.  
  797.       if (strlen(cmd) >= minlen)
  798.          {
  799.          strcpy(command, cpoint->Name);
  800.          Upper(command);
  801.  
  802.          if (!strncmp(command, cmd, strlen(cmd)) && ((cpoint->Level >= 0 && cpoint->Level <= KMS_LC->Session.CurrentUser->UserData.Level)
  803.                                                 || (cpoint->Level < 0 && -cpoint->Level == KMS_LC->Session.CurrentUser->UserData.Level)))
  804.             result = cpoint->ID;
  805.          }
  806.  
  807.       cpoint = cpoint->Node.mln_Succ;
  808.       }
  809.  
  810.    return result;
  811.    }
  812.  
  813. ///
  814.  
  815. /***************************************
  816.  * Kommando-Parameter prüfen           *
  817.  ***************************************
  818.  * I: Stelle des Parameters, Wort      *
  819.  * O: TRUE: Gefunden, FALSE: Nicht     *
  820.  ***************************************/
  821.  
  822. /// "CmpArg"
  823.  
  824. BOOL CmpArg(UBYTE idx, STRPTR string)
  825.    {
  826.    if (CmdArgC > idx && !stricmp(CmdArgV[idx], string))
  827.       return TRUE;
  828.    else
  829.       return FALSE;
  830.    }
  831.  
  832. ///
  833.  
  834. /*******************************************
  835.  * MsgHeader-Steuercodes uebersetzen       *
  836.  *******************************************
  837.  * I: InString, OutString, Max. Laenge     *
  838.  * O: OK: OutString / Fehler: NULL         *
  839.  *******************************************/
  840.  
  841. /// "MsgStringParse"
  842.  
  843. extern STRPTR RFromName;
  844. extern STRPTR RFromAddr;
  845. extern STRPTR RToName;
  846. extern STRPTR RToAddr;
  847. extern STRPTR RCreationDate;
  848. extern STRPTR RGroup;
  849. extern STRPTR RSubject;
  850.  
  851. STRPTR MsgStringParse(STRPTR qs, STRPTR line, UWORD maxlen)
  852.    {
  853.    UWORD qspos = 0, linpos = 0;
  854.  
  855.    STRPTR rfromname = "";
  856.    if (RFromName) rfromname = RFromName;
  857.    STRPTR rfromaddr = "";
  858.    if (RFromAddr) rfromaddr = RFromAddr;
  859.    STRPTR rtoname = "";
  860.    if (RToName) rtoname = RToName;
  861.    STRPTR rtoaddr = "";
  862.    if (RToAddr) rtoaddr = RToAddr;
  863.    STRPTR rcreationdate = "";
  864.    if (RCreationDate) rcreationdate = RCreationDate;
  865.    STRPTR rgroup = "";
  866.    if (RGroup) rgroup = RGroup;
  867.    STRPTR rsubject = "";
  868.    if (RSubject) rsubject = RSubject;
  869.  
  870.    line[linpos] = '\0';
  871.  
  872.    while(qs[qspos])
  873.       {
  874.       while(linpos < maxlen && qs[qspos] != '\0' && qs[qspos] != '%')
  875.          line[linpos++] = qs[qspos++];
  876.  
  877.       if (linpos < maxlen && qs[qspos] == '%' && qs[qspos+1] != '\0' && qs[qspos+1] != '%')
  878.          {
  879.          line[linpos] = '\0';
  880.  
  881.          switch(qs[++qspos])
  882.             {
  883.             case 'g':
  884.                if (strlen(rgroup))
  885.                   strncat(line, rgroup, maxlen-strlen(line));
  886.                else
  887.                   strncat(line, "-MAIL-", maxlen-strlen(line));
  888.                line[maxlen] = '\0';
  889.                linpos = strlen(line);
  890.                break;
  891.             case 'f':
  892.                strncat(line, rfromname, maxlen-strlen(line));
  893.                line[maxlen] = '\0';
  894.                linpos = strlen(line);
  895.                break;
  896.             case 'v':
  897.                strncat(line, rfromname, maxlen-strlen(line));
  898.                line[maxlen] = '\0';
  899.                while(line[linpos] != ' ' && line[linpos] != '\0')
  900.                   linpos++;
  901.                line[linpos] = '\0';
  902.                break;
  903.             case 't':
  904.                strncat(line, rtoname, maxlen-strlen(line));
  905.                line[maxlen] = '\0';
  906.                linpos = strlen(line);
  907.                break;
  908.             case 'd':
  909.                strncat(line, rcreationdate, maxlen-strlen(line));
  910.                line[maxlen] = '\0';
  911.                linpos = strlen(line);
  912.                break;
  913.             case 's':
  914.                strncat(line, rsubject, maxlen-strlen(line));
  915.                line[maxlen] = '\0';
  916.                linpos = strlen(line);
  917.                break;
  918.             case 'F':
  919.                strncat(line, rfromaddr, maxlen-strlen(line));
  920.                line[maxlen] = '\0';
  921.                linpos = strlen(line);
  922.                break;
  923.             case 'T':
  924.                strncat(line, rtoaddr, maxlen-strlen(line));
  925.                line[maxlen] = '\0';
  926.                linpos = strlen(line);
  927.                break;
  928.             default:
  929.                line[linpos++] = qs[qspos];
  930.                break;
  931.             }
  932.  
  933.          qspos++;
  934.          }
  935.       else if (linpos < maxlen && qs[qspos] == '%' && qs[qspos+1] == '%') /* "%%" */
  936.          {
  937.          line[linpos++] = qs[qspos++];
  938.          qspos++;
  939.          }
  940.       else if (linpos < maxlen && qs[qspos] != '\0') /* Fall "%\0" */
  941.          line[linpos++] = qs[qspos++];
  942.  
  943.       if (linpos >= maxlen)
  944.          {
  945.          line[maxlen] = '\0';
  946.          return line;
  947.          }
  948.       }
  949.  
  950.    line[linpos] = '\0';
  951.  
  952.    return line;
  953.    }
  954.  
  955. ///
  956.  
  957. /*******************************************
  958.  * Standard Steuercodes uebersetzen        *
  959.  *******************************************
  960.  * I: InString, OutString, Max. Laenge     *
  961.  * O: OK: OutString / Fehler: NULL         *
  962.  *******************************************/
  963.  
  964. /// "StdStringParse"
  965.  
  966. static parsecalls = 0;
  967.  
  968. STRPTR StdStringParse(STRPTR qs, STRPTR line, UWORD maxlen)
  969.    {
  970.    UWORD qspos = 0, linpos = 0;
  971.    LONG n;
  972.    TEXT numbuff[LEN_NUMBER+1], timebuff[LEN_MAKETIME+1];
  973.    TEXT dosbuff[LEN_DOSPATH+1];
  974.    TEXT outbuff[LEN_PARSEOUT+1]; /* Für Rekursion! Achtung Stack! */
  975.  
  976.    line[linpos] = '\0';
  977.  
  978.    /* Nur EIN Rekursionsaufruf erlaubt! */
  979.  
  980.    if (parsecalls++ == 2)
  981.       {
  982.       parsecalls--;
  983.       return line;
  984.       }
  985.  
  986.    while(qs[qspos])
  987.       {
  988.       while(linpos < maxlen && qs[qspos] != '\0' && qs[qspos] != '%')
  989.          line[linpos++] = qs[qspos++];
  990.  
  991.       if (linpos < maxlen && qs[qspos] == '%' && qs[qspos+1] != '\0' && qs[qspos+1] != '%')
  992.          {
  993.          line[linpos] = '\0';
  994.  
  995.          /* Steuercode interpretieren */
  996.  
  997.          switch(qs[++qspos])
  998.             {
  999.             case '1': /* Vordergrund-Farben */
  1000.             case '2':
  1001.             case '3':
  1002.             case '4':
  1003.             case '5':
  1004.             case '6':
  1005.             case '7':
  1006.             case '8':
  1007.                if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1008.                   {
  1009.                   TEXT farbe[3];
  1010.                   farbe[0] = qs[qspos];
  1011.                   farbe[1] = 'm';
  1012.                   farbe[2] = '\0';
  1013.                   strncat(line, "\033[3", maxlen-strlen(line));
  1014.                   line[maxlen] = '\0';
  1015.                   strncat(line, farbe, maxlen-strlen(line));
  1016.                   line[maxlen] = '\0';
  1017.                   linpos = strlen(line);
  1018.                   }
  1019.                break;
  1020.             case '(': /* Hintergrund-Farben */
  1021.             case ')':
  1022.             case '*':
  1023.             case '+':
  1024.             case ',':
  1025.             case '-':
  1026.             case '.':
  1027.             case '/':
  1028.                if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1029.                   {
  1030.                   TEXT farbe[3];
  1031.                   farbe[0] = qs[qspos] + 8;
  1032.                   farbe[1] = 'm';
  1033.                   farbe[2] = '\0';
  1034.                   strncat(line, "\033[4", maxlen-strlen(line));
  1035.                   line[maxlen] = '\0';
  1036.                   strncat(line, farbe, maxlen-strlen(line));
  1037.                   line[maxlen] = '\0';
  1038.                   linpos = strlen(line);
  1039.                   }
  1040.                break;
  1041.             case 'B': /* Bold */
  1042.                if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1043.                   {
  1044.                   strncat(line, BOLD, maxlen-strlen(line));
  1045.                   line[maxlen] = '\0';
  1046.                   linpos = strlen(line);
  1047.                   }
  1048.                break;
  1049.             case 'E': /* ESC */
  1050.                line[linpos++] = '\033';
  1051.                break;
  1052.             case 'G': /* Bell */
  1053.                line[linpos++] = '\7';
  1054.                break;
  1055.             case 'I': /* Tab */
  1056.                line[linpos++] = '\t';
  1057.                break;
  1058.             case 'J': /* Line Feed */
  1059.                line[linpos++] = '\n';
  1060.                break;
  1061.             case 'L': /* Soft-CLS */
  1062.                if (!(KMS_LC->Session.CurrentUser->UserData.Flags & UF_CLS))
  1063.                   break;
  1064.                if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1065.                   {
  1066.                   strncat(line, CLS, maxlen-strlen(line));
  1067.                   line[maxlen] = '\0';
  1068.                   linpos = strlen(line);
  1069.                   }
  1070.                else
  1071.                   line[linpos++] = '\f';
  1072.                break;
  1073.             case 'M': /* Carriage Return */
  1074.                line[linpos++] = '\r';
  1075.                break;
  1076.             case 'N': /* Neue Zeile */
  1077.                line[linpos++] = '\r';
  1078.                if (linpos < maxlen)
  1079.                   line[linpos++] = '\n';
  1080.                break;
  1081.             case 'O': /* Normal */
  1082.                if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1083.                   {
  1084.                   strncat(line, OFF, maxlen-strlen(line));
  1085.                   line[maxlen] = '\0';
  1086.                   linpos = strlen(line);
  1087.                   }
  1088.                break;
  1089.             case 'R': /* Reverse */
  1090.                if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1091.                   {
  1092.                   strncat(line, INV, maxlen-strlen(line));
  1093.                   line[maxlen] = '\0';
  1094.                   linpos = strlen(line);
  1095.                   }
  1096.                break;
  1097.             case 'X': /* Hard-CLS */
  1098.                if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1099.                   {
  1100.                   strncat(line, CLS, maxlen-strlen(line));
  1101.                   line[maxlen] = '\0';
  1102.                   linpos = strlen(line);
  1103.                   }
  1104.                else
  1105.                   line[linpos++] = '\f';
  1106.                break;
  1107.             case 'a': /* Verbindungszeit in Minuten */
  1108.                n = (time(NULL) - KMS_LC->Session.LoginTime) / 60;
  1109.                sprintf(numbuff, "%ld", n);
  1110.                strncat(line, numbuff, maxlen-strlen(line));
  1111.                line[maxlen] = '\0';
  1112.                linpos = strlen(line);
  1113.                break;
  1114.             case 'b': /* Restzeit in Minuten */
  1115.                if (!KMS_LC->Session.MaxConnectTime)
  1116.                   strncat(line, "-?-", maxlen - strlen(line));
  1117.                else
  1118.                   {
  1119.                   n = KMS_LC->Session.MaxConnectTime * 60 - time(NULL) + KMS_LC->Session.LoginTime;
  1120.                   n /= 60;
  1121.                   if (n < 0)
  1122.                      n = 0;
  1123.                   sprintf(numbuff, "%ld", n);
  1124.                   strncat(line, numbuff, maxlen-strlen(line));
  1125.                   }
  1126.                line[maxlen] = '\0';
  1127.                linpos = strlen(line);
  1128.                break;
  1129.             case 'c': /* Verbindungszeit HH:MM:SS */
  1130.                MakeTime(timebuff, KMS_LC->Session.LoginTime, 0);
  1131.                strncat(line, timebuff+9, maxlen-strlen(line));
  1132.                line[maxlen] = '\0';
  1133.                linpos = strlen(line);
  1134.                break;
  1135.             case 'd': /* Restzeit HH:MM:SS */
  1136.                if (!KMS_LC->Session.MaxConnectTime)
  1137.                   strncat(line, "-?-", maxlen - strlen(line));
  1138.                else
  1139.                   {
  1140.                   n = KMS_LC->Session.MaxConnectTime * 60 - time(NULL) + KMS_LC->Session.LoginTime;
  1141.                   if (n < 0)
  1142.                      n = 0;
  1143.                   sprintf(timebuff, "%02d:%02d:%02d", n/3600, (n%3600)/60, n%60);
  1144.                   strncat(line, timebuff, maxlen-strlen(line));
  1145.                   }
  1146.                line[maxlen] = '\0';
  1147.                linpos = strlen(line);
  1148.                break;
  1149.             case 'e': /* Username */
  1150.                strncat(line, KMS_LC->Session.CurrentUser->UserData.Name, maxlen-strlen(line));
  1151.                line[maxlen] = '\0';
  1152.                linpos = strlen(line);
  1153.                break;
  1154.             case 'f': /* Realname */
  1155.                strncat(line, KMS_LC->Session.CurrentUser->UserData.RealName, maxlen-strlen(line));
  1156.                line[maxlen] = '\0';
  1157.                linpos = strlen(line);
  1158.                break;
  1159.             case 'g': /* Stadt */
  1160.                strncat(line, KMS_LC->Session.CurrentUser->UserData.City, maxlen-strlen(line));
  1161.                line[maxlen] = '\0';
  1162.                linpos = strlen(line);
  1163.                break;
  1164.             case 'h': /* Level */
  1165.                sprintf(numbuff, "%d", KMS_LC->Session.CurrentUser->UserData.Level);
  1166.                strncat(line, numbuff, maxlen-strlen(line));
  1167.                line[maxlen] = '\0';
  1168.                linpos = strlen(line);
  1169.                break;
  1170.             case 'i': /* LastCall Date */
  1171.                MakeTime(timebuff, 0, KMS_LC->Session.CurrentUser->UserData.LastCall);
  1172.                timebuff[8] = '\0';
  1173.                strncat(line, timebuff, maxlen-strlen(line));
  1174.                line[maxlen] = '\0';
  1175.                linpos = strlen(line);
  1176.                break;
  1177.             case 'j': /* LastCall Time */
  1178.                MakeTime(timebuff, 0, KMS_LC->Session.CurrentUser->UserData.LastCall);
  1179.                strncat(line, &timebuff[9], maxlen-strlen(line));
  1180.                line[maxlen] = '\0';
  1181.                linpos = strlen(line);
  1182.                break;
  1183.             case 'k': /* Anrufe bisher */
  1184.                sprintf(numbuff, "%d", KMS_LC->Session.CurrentUser->UserData.Calls);
  1185.                strncat(line, numbuff, maxlen-strlen(line));
  1186.                line[maxlen] = '\0';
  1187.                linpos = strlen(line);
  1188.                break;
  1189.             case 'l': /* Prompt */
  1190.                StdStringParse(KMS_LC->Session.CurrentUser->UserData.Prompt, outbuff, LEN_PARSEOUT);
  1191.                strncat(line, outbuff, maxlen-strlen(line));
  1192.                line[maxlen] = '\0';
  1193.                linpos = strlen(line);
  1194.                break;
  1195.             case 'm': /* Aktuelle Zeit */
  1196.                MakeTime(timebuff, 0, 0);
  1197.                strncat(line, &timebuff[9], maxlen-strlen(line));
  1198.                line[maxlen] = '\0';
  1199.                linpos = strlen(line);
  1200.                break;
  1201.             case 'n': /* Aktuelles Datum */
  1202.                MakeTime(timebuff, 0, 0);
  1203.                timebuff[8] = '\0';
  1204.                strncat(line, timebuff, maxlen-strlen(line));
  1205.                line[maxlen] = '\0';
  1206.                linpos = strlen(line);
  1207.                break;
  1208.             case 'o': /* TempDir */
  1209.                if (strlen(line) + strlen(KMSBase->TempDir) <= maxlen)
  1210.                   {
  1211.                   strcat(line, KMSBase->TempDir);
  1212.                   linpos = strlen(line);
  1213.                   }
  1214.                break;
  1215.             case 'p': /* Current Path */
  1216.                CreatePath(KMS_LC->Session.CurrentArea);
  1217.                strncat(line, PathString, maxlen-strlen(line));
  1218.                line[maxlen] = '\0';
  1219.                linpos = strlen(line);
  1220.                break;
  1221.             case 'q': /* SerDevice */
  1222.                if (strlen(line) + strlen(KMS_LC->SerDevice) <= maxlen)
  1223.                   {
  1224.                   strcat(line, KMS_LC->SerDevice);
  1225.                   linpos = strlen(line);
  1226.                   }
  1227.                break;
  1228.             case 'r': /* BinDir */
  1229.                if (strlen(line) + strlen(KMSBase->BinDir) <= maxlen)
  1230.                   {
  1231.                   strcat(line, KMSBase->BinDir);
  1232.                   linpos = strlen(line);
  1233.                   }
  1234.                break;
  1235.             case 's': /* Zeilen */
  1236.                sprintf(numbuff, "%d", KMS_LC->Session.CurrentUser->UserData.PageLen);
  1237.                strncat(line, numbuff, maxlen-strlen(line));
  1238.                line[maxlen] = '\0';
  1239.                linpos = strlen(line);
  1240.                break;
  1241.             case 't': /* Spalten */
  1242.                sprintf(numbuff, "%d", KMS_LC->Session.CurrentUser->UserData.LineLen);
  1243.                strncat(line, numbuff, maxlen-strlen(line));
  1244.                line[maxlen] = '\0';
  1245.                linpos = strlen(line);
  1246.                break;
  1247.             case 'u': /* User-Dir */
  1248.                strcpy(dosbuff, KMSBase->UserDir);
  1249.                strcat(dosbuff, KMS_LC->Session.CurrentUser->UserData.Name);
  1250.                ConvertSpace(dosbuff);
  1251.                if (strlen(line) + strlen(dosbuff) <= maxlen)
  1252.                   {
  1253.                   strcat(line, dosbuff);
  1254.                   linpos = strlen(line);
  1255.                   }
  1256.                break;
  1257.             case 'v': /* Variables Argument */
  1258.                if (PPArg)
  1259.                   {
  1260.                   strncat(line, PPArg, maxlen-strlen(line));
  1261.                   line[maxlen] = '\0';
  1262.                   linpos = strlen(line);
  1263.                   }
  1264.                break;
  1265.             case 'w': /* Variables Argument 2 */
  1266.                if (PPArg2)
  1267.                   {
  1268.                   strncat(line, PPArg2, maxlen-strlen(line));
  1269.                   line[maxlen] = '\0';
  1270.                   linpos = strlen(line);
  1271.                   }
  1272.                break;
  1273.             case 'x': /* Variables Argument 3 */
  1274.                if (PPArg3)
  1275.                   {
  1276.                   strncat(line, PPArg3, maxlen-strlen(line));
  1277.                   line[maxlen] = '\0';
  1278.                   linpos = strlen(line);
  1279.                   }
  1280.                break;
  1281.             case 'y': /* Variables Argument 4 */
  1282.                if (PPArg4)
  1283.                   {
  1284.                   strncat(line, PPArg4, maxlen-strlen(line));
  1285.                   line[maxlen] = '\0';
  1286.                   linpos = strlen(line);
  1287.                   }
  1288.                break;
  1289.             case 'z': /* SerUnit */
  1290.                sprintf(numbuff, "%d", KMS_LC->SerUnit);
  1291.                if (strlen(line) + strlen(numbuff) <= maxlen)
  1292.                   {
  1293.                   strcat(line, numbuff);
  1294.                   linpos = strlen(line);
  1295.                   }
  1296.                break;
  1297.             default:
  1298.                line[linpos++] = qs[qspos];
  1299.                break;
  1300.             }
  1301.  
  1302.          qspos++;
  1303.          }
  1304.       else if (linpos < maxlen && qs[qspos] == '%' && qs[qspos+1] == '%') /* Fall "%%" */
  1305.          {
  1306.          line[linpos++] = qs[qspos++];
  1307.          qspos++;
  1308.          }
  1309.       else if (linpos < maxlen && qs[qspos] != '\0') /* Fall "%\0" */
  1310.          line[linpos++] = qs[qspos++];
  1311.  
  1312.       if (linpos >= maxlen)
  1313.          {
  1314.          line[maxlen] = '\0';
  1315.          parsecalls--;
  1316.  
  1317.          return line;
  1318.          }
  1319.       }
  1320.  
  1321.    line[linpos] = '\0';
  1322.  
  1323.    parsecalls--;
  1324.  
  1325.    return line;
  1326.    }
  1327.  
  1328. ///
  1329.  
  1330. /***************************************
  1331.  * Parsing von Range-Angaben           *
  1332.  ***************************************
  1333.  * I: Range-Liste                      *
  1334.  * O: Erfolg TRUE/FALSE                *
  1335.  ***************************************/
  1336.  
  1337. /// "ParseRange"
  1338.  
  1339. BOOL ParseRange(STRPTR range)
  1340.    {
  1341.    TEXT ws[] = ",";
  1342.    STRPTR arg, minus;
  1343.    UMSMsgNum num;
  1344.  
  1345.    UMSSelectTags(MyUMSAccount, UMSTAG_SelWriteLocal, TRUE,
  1346.                                UMSTAG_SelUnset,      KMSLSTATF_InRange,
  1347.                                TAG_DONE);
  1348.  
  1349.    for (arg = strtok(range, ws); arg; arg = strtok(NULL, ws))
  1350.       {
  1351.       if (minus = strchr(arg, '-'))
  1352.          {
  1353.          if (minus == arg) /* "-x" */
  1354.             {
  1355.             UMSSelectTags(MyUMSAccount, UMSTAG_SelStop,       atol(arg+1)+1,
  1356.                                         UMSTAG_SelWriteLocal, TRUE,
  1357.                                         UMSTAG_SelSet,        KMSLSTATF_InRange,
  1358.                                         TAG_DONE);
  1359.             }
  1360.          else if (*(minus + 1) == '\0') /* "x-" */
  1361.             {
  1362.             UMSSelectTags(MyUMSAccount, UMSTAG_SelStart,      atol(arg),
  1363.                                         UMSTAG_SelWriteLocal, TRUE,
  1364.                                         UMSTAG_SelSet,        KMSLSTATF_InRange,
  1365.                                         TAG_DONE);
  1366.             }
  1367.          else /* "x-y" */
  1368.             {
  1369.             UMSSelectTags(MyUMSAccount, UMSTAG_SelStart,      atol(arg),
  1370.                                         UMSTAG_SelStop,       atol(minus+1)+1,
  1371.                                         UMSTAG_SelWriteLocal, TRUE,
  1372.                                         UMSTAG_SelSet,        KMSLSTATF_InRange,
  1373.                                         TAG_DONE);
  1374.             }
  1375.          }
  1376.       else if (atol(arg)) /* "x" */
  1377.          UMSSelectTags(MyUMSAccount, UMSTAG_SelMsg,        atol(arg),
  1378.                                      UMSTAG_SelWriteLocal, TRUE,
  1379.                                      UMSTAG_SelSet,        KMSLSTATF_InRange,
  1380.                                      TAG_DONE);
  1381.       }
  1382.  
  1383.    SelectArea(KMS_LC->Session.CurrentArea->AreaData.MBName);
  1384.  
  1385.    UMSSelectTags(MyUMSAccount, UMSTAG_SelReadLocal, TRUE,
  1386.                                UMSTAG_SelWriteLocal, TRUE,
  1387.                                UMSTAG_SelMask,      KMSLSTATF_InRange|KMSLSTATF_InGroup,
  1388.                                UMSTAG_SelMatch,     KMSLSTATF_InRange,
  1389.                                UMSTAG_SelUnset,     KMSLSTATF_InRange,
  1390.                                TAG_DONE);
  1391.  
  1392.    num = UMSSelectTags(MyUMSAccount, UMSTAG_SelReadLocal, TRUE,
  1393.                                      UMSTAG_SelMask,      KMSLSTATF_InRange,
  1394.                                      UMSTAG_SelMatch,     KMSLSTATF_InRange,
  1395.                                      TAG_DONE);
  1396.  
  1397.    if (!num)
  1398.       return FALSE;
  1399.    else
  1400.       return TRUE;
  1401.    }
  1402.  
  1403. ///
  1404.  
  1405. /***************************************
  1406.  * Chat-Interpreter                    *
  1407.  ***************************************
  1408.  * I: ---                              *
  1409.  * O: keepgoing                        *
  1410.  ***************************************/
  1411.  
  1412. /// "ChatInterpreter"
  1413.  
  1414. BOOL ChatInterpreter(STRPTR buffer)
  1415.    {
  1416.    BOOL keepgoing = TRUE;
  1417.  
  1418.    if (buffer[0] != '.' && buffer[0] != ':')
  1419.       {
  1420.       if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1421.          ChatOut(buffer, CO_METOO);
  1422.       else
  1423.          ChatOut(buffer, 0);
  1424.       }
  1425.    else
  1426.       keepgoing = ChatCmd(buffer);
  1427.  
  1428.    return keepgoing;
  1429.    }
  1430.  
  1431. ///
  1432.  
  1433. /***************************************
  1434.  * Chat-Kommando auswerten             *
  1435.  ***************************************
  1436.  * I: ---                              *
  1437.  * O: Chat-Exit Ja/Nein                *
  1438.  ***************************************/
  1439.  
  1440. /// "ChatCmd"
  1441.  
  1442. BOOL ChatCmd(STRPTR buffer)
  1443.    {
  1444.    TEXT buff[LEN_MAXLINE+1];
  1445.  
  1446.    if (*buffer == ':')
  1447.       {
  1448.       ChatOut(buffer+1, CO_METOO|CO_EMOTE);
  1449.       return TRUE;
  1450.       }
  1451.    else if (!stricmp(buffer, ".w"))
  1452.       {
  1453.       struct KMSNode *member = KMSBase->MemberList.mlh_Head;
  1454.  
  1455.       TakeMSem(FALSE);
  1456.  
  1457.       while(member->Node.mln_Succ)
  1458.          {
  1459.          if (member->LCPtr->Session.CommMode == CM_CHAT)
  1460.             {
  1461.             sprintf(buff, "%2d> %s (%s)", member->LCPtr->ID, member->LCPtr->Session.CurrentUser->UserData.Name, member->LCPtr->Session.ChatChannel);
  1462.             ChatPrint(buff);
  1463.             }
  1464.  
  1465.          member = member->Node.mln_Succ;
  1466.          }
  1467.  
  1468.       DropMSem();
  1469.       
  1470.       return TRUE;
  1471.       }
  1472.    else if (buffer[1] == 'k')
  1473.       {
  1474.       if (strlen(buffer) > 2)
  1475.          {
  1476.          sprintf(buff, "------ %s ------", KMS_LC->Session.CurrentUser->UserData.Name);
  1477.          ChatOut(buff, CO_NOPROMPT);
  1478.  
  1479.          strncpy(KMS_LC->Session.ChatChannel, buffer+2, 15);
  1480.          KMS_LC->Session.ChatChannel[15] = '\0';
  1481.  
  1482.          sprintf(buff, "++++++ %s ++++++", KMS_LC->Session.CurrentUser->UserData.Name);
  1483.          ChatOut(buff, CO_NOPROMPT);
  1484.  
  1485.          sprintf(buff, "===> [%s]", KMS_LC->Session.ChatChannel);
  1486.          ChatPrint(buff);
  1487.  
  1488.          sprintf(buff, CHAT_INCLR, KMS_LC->Session.CurrentUser->UserData.PageLen-4);
  1489.          Print(buff, PF_NOLF|PF_NOBRK);
  1490.          sprintf(buff, CHAT_POS, KMS_LC->Session.CurrentUser->UserData.PageLen-4);
  1491.          Print(buff, PF_NOLF|PF_NOBRK);
  1492.          PPArg = KMS_LC->Session.ChatChannel;
  1493.          SysMsg(CHAT_STATUS_LINE);
  1494.          PPArg = NULL;
  1495.          }
  1496.  
  1497.       return TRUE;
  1498.       }
  1499.    else if (!stricmp(buffer, ".x"))
  1500.       return FALSE;
  1501.    else
  1502.       {
  1503.       if (KMS_LC->Session.CurrentUser->UserData.Flags & UF_EMU_ANSI)
  1504.          ChatOut(buffer, CO_METOO);
  1505.       else
  1506.          ChatOut(buffer, 0);
  1507.       
  1508.       return TRUE;
  1509.       }
  1510.    }
  1511.  
  1512. ///
  1513.